package tp.pr5.instructions;

import tp.pr5.NavigationModule;
import tp.pr5.RobotEngine;
import tp.pr5.instructions.exceptions.InstructionExecutionException;
import tp.pr5.instructions.exceptions.WrongInstructionFormatException;
import tp.pr5.items.Item;
import tp.pr5.items.ItemContainer;

public class PickInstruction extends UndoAble{
	private String objeto;
	private NavigationModule nvm;
	private ItemContainer rbtCont;
	private Item lastObject;
	private RobotEngine rbt;
	
	public PickInstruction(){
		this.objeto = null;
	}
	
	public PickInstruction(String objeto) {
		this.objeto = objeto;
	}

	@Override
	public Instruction parse(String cad) throws WrongInstructionFormatException {
		String[] lineArr = cad.trim().replaceAll(" +", " ").split(" ");	//parte la cadena introducida en palabras
		
		
			String accion = "";
			String id = "";
			if(lineArr.length>=1) accion = lineArr[0]; //si existe alguna palabra, la primera serÃ¡ la acciÃ³n
			if(lineArr.length==2) id = lineArr[1]; //si hay mÃ¡s de una palabra, la segunda serÃ¡ la id
			
			if(accion.equalsIgnoreCase("PICK") || accion.equalsIgnoreCase("COGER")){//si la acciÃ³n introducida es PICK
				if(id != ""){
					return new PickInstruction(id);
				}else{
					throw new WrongInstructionFormatException();
				}
			}else{
				throw new WrongInstructionFormatException();
			}		
		
		
	}

	@Override
	public String getHelp() {
		return "     PICK|COGER <ITEM>";
	}

	@Override
	public void configureContext(RobotEngine engine,
			NavigationModule navigation, ItemContainer robotContainer) {
		this.nvm = navigation;
		this.rbtCont = robotContainer;
		this.rbt = engine; 
	}

	@Override
	public void execute() throws InstructionExecutionException {		
		ItemContainer icPlace = this.nvm.getCurrentPlace().getInventory();
		ItemContainer icSelf = this.rbtCont;
		if(!icSelf.containsItem(this.objeto) && icPlace.containsItem(this.objeto) ){//si puede cogerlo
			Item ob = this.nvm.pickItemFromCurrentPlace(this.objeto);			
			icSelf.addItem(ob);
			this.rbt.emitInventoryChanged("WALL·E says: I am happy! Now I have "+this.objeto);
			
			this.lastObject = ob;
		}else{// si no puede
			if(icSelf.containsItem(this.objeto))
				throw new InstructionExecutionException("WALL·E says: I am stupid! I already have the object "+this.objeto);
			if(!icPlace.containsItem(this.objeto))
				throw new InstructionExecutionException("WALL·E says: Ooops, this place has not the object "+this.objeto);			
		}
		
	}
	
	@Override
	public boolean isUndoAble() {

		return true;
	}

	/**
	 * reverts the last instruction
	 * @throws InstructionExecutionException 
	 */
	public void undo() throws InstructionExecutionException {
		this.nvm.getCurrentPlace().getInventory().addItem(this.lastObject);
		this.rbtCont.getItemInventory().remove(this.lastObject);
		this.rbt.emitInventoryChanged("");
	}
}
